package com.andy.qi.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import com.andy.qi.domain.nogame.NoGame;
import com.andy.qi.domain.nogame.NoSeat;
import com.andy.qi.domain.room.Room;
import com.andy.qi.util.ListUtils;

public abstract class GameMgr extends TimerTask {
    
    public final static int TYPE_TONG = 0;  // 筒
    public final static int TYPE_TIAO = 1;  // 条
    public final static int TYPE_WAN = 2;  // 万
    public final static int TYPE_OTHER = -1;  // 其他
    
    
    public final static int TONG_ONE = 0;
    
    public final static int TONG_NINE = 8;
    
    
    public final static int TIAO_ONE = 9;
    
    public final static int TIAO_NINE = 17;
    
    
    public final static int WAN_ONE = 18;
    
    public final static int WAN_NINE = 26;
    
    
    int ACTION_CHUPAI = 1;
    int ACTION_MOPAI = 2;
    int ACTION_PENG = 3;
    int ACTION_GANG = 4;
    int ACTION_HU = 5;
    int ACTION_ZIMO = 6;
    
    

    private static Timer timer = new Timer(true);
    
    List<String> dissolvingList = new ArrayList<>();
    Map<String, NoGame> games = new HashMap<>();
    Map<String, NoSeat> gameSeatsOfUsers = new HashMap<>();
    Mjutils mjutils = new Mjutils();
    int gamesIdBase = 0;
    RoomMgr roomMgr;
    UserMgr userMgr;
    DBUtils db;

    
    public GameMgr(RoomMgr roomMgr) {
        this.roomMgr = roomMgr;
        this.userMgr = roomMgr.userMgr;
        this.db = roomMgr.db;
        timer.schedule(this, 1000, 1000);
    }
    
    
    public abstract void setReady(String userId);

    public abstract void huanSanZhang(String userId, int p1, int p2, int p3);

    public abstract void dingQue(String userId, int que);

    public abstract void chuPai(String userId, int pai);

    public abstract void peng(String userId);

    public abstract void gang(String userId, int pai);

    public abstract void hu(String userId);

    public abstract void guo(String userId);

    public abstract boolean hasBegan(String roomId);

    public abstract Room dissolveRequest(String roomId, String userId);

    public abstract Room dissolveAgree(String roomId, String userId, boolean b);

    public abstract void doDissolve(String roomId);
    
    public int getMJType(int id){
        if(id >= TONG_ONE && id <= TONG_NINE){
            //筒
            return TYPE_TONG;
        }
        else if(id >= TIAO_ONE && id <= TIAO_NINE){
            //条
            return TYPE_TIAO;
        }
        else if(id >= WAN_ONE && id <= WAN_NINE){
            //万
            return TYPE_WAN;
        }
        return TYPE_OTHER;
    }
    
    /**
     * 洗牌
     * @param game
     */
    public void shuffle(NoGame game) {
        
        int[] mahjongs = game.mahjongs;

        /*
        int idx = 0;
        for(int i = 0; i < 12; ++i){
            game.mahjongs[idx++] = 0;
        }

        for(int i = 0; i < 12; ++i){
            game.mahjongs[idx++] = 1;
        }

        for(int i = 0; i < 12; ++i){
            game.mahjongs[idx++] = 2;
        }

        for(int i = 0; i < 12; ++i){
            game.mahjongs[idx++] = 3;
        }


        for(int i = idx; i < game.mahjongs.length; ++i){
            game.mahjongs[i] = 4;
        }
        return;
        */

        //筒 (0 ~ 8 表示筒子
        int index = 0;
        for(int i = TONG_ONE; i <= TONG_NINE; ++i){
            for(int c = 0; c < 4; ++c){
                mahjongs[index] = i;
                index++;
            }
        }

        //条 9 ~ 17表示条子
        for(int i = TIAO_ONE; i <= TIAO_NINE; ++i){
            for(int c = 0; c < 4; ++c){
                mahjongs[index] = i;
                index++;
            }
        }

        //万
        //条 18 ~ 26表示万
        for(int i = WAN_ONE; i <= WAN_NINE; ++i){
            for(int c = 0; c < 4; ++c){
                mahjongs[index] = i;
                index++;
            }
        }

        for(int i = 0; i < mahjongs.length; ++i) {
            int lastIndex = mahjongs.length - 1 - i;
            int idx = (int)Math.floor(Math.random() * lastIndex);
            int t = mahjongs[idx];
            mahjongs[idx] = mahjongs[lastIndex];
            mahjongs[lastIndex] = t;
        }
    }
    
    public boolean isSameType(int type, List<Integer> arr){
        for(int i = 0; i < arr.size(); ++i){
            int t = getMJType(arr.get(i));
            if(type != -1 && type != t){
                return false;
            }
            type = t;
        }
        return true; 
    }
    
    /**
     * 清一色
     * @param gameSeatData
     * @return
     */
    public boolean isQingYiSe(NoSeat gameSeatData){
        int type = getMJType(gameSeatData.holds.get(0));

        //检查手上的牌
        if(!isSameType(type,gameSeatData.holds)){
            return false;
        }

        //检查杠下的牌
        if(!isSameType(type,gameSeatData.angangs)){
            return false;
        }
        if(!isSameType(type,gameSeatData.wangangs)){
            return false;
        }
        if(!isSameType(type,gameSeatData.diangangs)){
            return false;
        }

        //检查碰牌
        if(!isSameType(type,gameSeatData.pengs)){
            return false;
        }
        return true;
    }

    
    public void destroy() {
        this.cancel();
    }
    
    public Integer getSeatIndex(String userId){
        Integer seatIndex = roomMgr.getUserSeat(userId);
        if(seatIndex == null){
            return null;
        }
        return seatIndex;
    }
    
    public NoGame getGameByUserID(String userId){
        String roomId = roomMgr.getUserRoom(userId);
        if(roomId == null){
            return null;
        }
        NoGame game = games.get(roomId);
        return game;
    }
    
    @Override
    public void run() {
        for(int i = dissolvingList.size() - 1; i >= 0; --i){
            String roomId = dissolvingList.get(i);
            
            Room roomInfo = roomMgr.getRoom(roomId);
            if(roomInfo != null && roomInfo.dr != null){
                if(System.currentTimeMillis() > roomInfo.dr.endTime){
                    System.out.println("delete room and games");
                    doDissolve(roomId);
                    ListUtils.splice(dissolvingList, i,1); 
                }
            }
            else{
                ListUtils.splice(dissolvingList, i,1);
            }
        }
    }
    
    public void setTimeout(TimerTask task, long delay) {
        timer.schedule(task, delay);
    }

}
